/*
 * File: stackimpl.cpp
 * -------------------
 * This file contains the list-based implementation of the
 * Stack class.
 */
#ifdef _stack_h
/*
 * Implementation notes: Stack constructor
 * ---------------------------------------
 * The constructor must create an empty linked list and then
 * initialize the fields of the object.
 */
template <typename ElemType>
Stack<ElemType>::Stack() {
    list = NULL;
    count = 0;
}
/*
 * Implementation notes: ~Stack destructor
 * ---------------------------------------
 * The destructor frees any memory allocated by the implementation.
 * Freeing this memory guarantees that the stack abstraction
 * will not "leak memory" in the process of running an
 * application.  Because clear frees each element it processes,
 * this implementation of the destructor uses that method.
 */
template <typename ElemType>
Stack<ElemType>::~Stack() {
    clear();
}
/*
 * Implementation notes: size, isEmpty, clear
 * ------------------------------------------
 * These implementations should be self-explanatory.
 */
template <typename ElemType>
int Stack<ElemType>::size() {
    return count;
}
template <typename ElemType>
bool Stack<ElemType>::isEmpty() {
    return count == 0;
}
template <typename ElemType>
void Stack<ElemType>::clear() {
    while (count > 0) {
        pop();
    }
}
/*
 * Implementation notes: push
 * --------------------------
 * This method chains a new element onto the list
 * where it becomes the top of the stack.
 */
template <typename ElemType>
void Stack<ElemType>::push(ElemType elem) {
    cellT *cell = new cellT;
    cell->data = elem;
    cell->link = list;
    list = cell;
    count++;
}
/*
 * Implementation notes: pop, peek
 * -------------------------------
 * These methods must check for an empty stack and report an
 * error if there is no top element.  The pop method must free
 * the cell to ensure that the implementation does not waste
 * heap storage as it executes.
 */
template <typename ElemType>
ElemType Stack<ElemType>::pop() {
    if (isEmpty()) {
        Error("pop: Attempting to pop an empty stack");
    }
    cellT *cell = list;
    ElemType result = cell->data;
    list = list->link;
    count--;
    delete cell;
    return result;
}
template <typename ElemType>
ElemType Stack<ElemType>::peek() {
    if (isEmpty()) {
        Error("peek: Attempting to peek at an empty stack");
    }
    return list->data;
}
#endif